<template>
  <div className="chat">
    <div className="chat-select">
      <el-select v-model="selectedModel"  placeholder="模型" size="large">
        <el-option  v-for="item in Models"  :key="item"  :label="item"  :value="item"/>
      </el-select>
      <el-button type="primary" class="chat-add-session-btn" style="margin: 20px;"  @click="handleClear">新增会话</el-button>
      <div style="display: flex;flex-direction: column;margin-bottom: 10px;">
       <!--  <el-tag v-for="item in hisList" :key="item" closable style="margin-bottom: 10px;overflow: hidden;">
           <span style="width: 150px;">{{ item }}</span>
        </el-tag> -->
      </div>
      
    </div>
   
    <div className="chat-area">     
      <div className="message">
        <div class="chat-box">
          <div v-for="(message, index) in messages" :key="index" 
              :class="['message', message.role]">
            <strong>{{ message.role === 'user' ? '你' : 'AI' }}:</strong>
            <div v-if="message.role === 'assistant' && index === messages.length - 1 && isStreaming" 
             class="markdown-content">
            <div v-html="renderMarkdown(streamingText)"></div>
            <span class="cursor">|</span>
          </div>
          <div v-else class="markdown-content" v-html="renderMarkdown(message.content)"></div>
      </div>
    </div>
      </div>
      <div className="message-input">
        <el-input
          type="textarea"
          :rows="3"
          :autosize="{ minRows: 3, maxRows: 6 }"
          v-model="userInput"
          @keydown.enter.native.prevent="sendMessage"
          :disabled="isStreaming"
          resize="none"
          ref="textareaRef"
        >
          <template #append>
            <el-button 
              type="primary" 
              @click="sendMessage" 
              :disabled="isStreaming || !userInput.trim()"
              :loading="isStreaming"
            >
              {{ isStreaming ? '生成中' : '发送' }}
            </el-button>
          </template>
        </el-input>
        <el-button @click="sendMessage" :disabled="isStreaming" type="primary" style="margin-left: 10px; margin-right: -10px">
          {{ isStreaming ? '生成中...' : '发送' }}
        </el-button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, watch, nextTick } from 'vue'
import { marked } from 'marked'
import hljs from 'highlight.js'
import 'highlight.js/styles/github.css'
import {getOllamaModels} from './tools/tools.js'

// 配置 marked 使用 highlight.js 高亮代码
marked.setOptions({
  highlight: function(code, lang) {
    const language = hljs.getLanguage(lang) ? lang : 'plaintext'
    return hljs.highlight(code, { language }).value
  },
  breaks: true,
  gfm: true
})

// 状态管理
const userInput = ref('')
const messages = ref([])
const isStreaming = ref(false)
const streamingText = ref('')
const selectedModel = ref('') // 默认模型
const Models = ref([])
const autoScroll = ref(true)
const hisList = ref([])
const session_id = crypto.randomUUID()
console.log(session_id)
// 初始化消息
onMounted( async () => {
  messages.value = [{ role: 'assistant', content: '你好！我是AI助手，请问有什么可以帮你的？' }]

  Models.value = await getOllamaModels()
  //await window.dbAPI.invoke('session:removeSession', {session_id:'5d386554-657a-4c92-8bcb-aa7c9b30481d'});
  //console.log(await window.dbAPI.invoke('session:getGroupSession', {session_id: 'f5006330-9184-44f0-8ff5-7ee90510faca'}));
})

const renderMarkdown = (text) => {
  return marked.parse(text || '')
}

// 发送消息
const sendMessage = async () => {
  if(selectedModel.value == ''){
    streamingText.value = '请选择模型 '
    messages.value[messages.value.length - 1].content = streamingText.value
    return
  } 
  if (!userInput.value.trim() || isStreaming.value) return

  // 添加用户消息
  messages.value.push({
    role: 'user',
    content: userInput.value
  })

  // 准备AI回复占位
  messages.value.push({
    role: 'assistant',
    content: ''
  })

  const prompt = userInput.value

  userInput.value = ''
  isStreaming.value = true
  streamingText.value = ''
  try {
    // 调用Ollama API获取流式响应
    const response = await fetch('http://localhost:11434/api/generate', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        model: selectedModel.value,
        prompt: prompt,
        stream: true
      })
    })

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`)
    }

    // 处理流式数据
    const reader = response.body.getReader()
    const decoder = new TextDecoder()

    while (true) {
      const { done, value } = await reader.read()
      if (done) break

      const chunk = decoder.decode(value)
      const lines = chunk.split('\n').filter((line) => line.trim() !== '')

      for (const line of lines) {
        try {
          const data = JSON.parse(line)
          if (data.response) {
            streamingText.value += data.response
            // 更新最后一条消息内容
            messages.value[messages.value.length - 1].content = streamingText.value
          
            // 自动滚动到底部
            if (autoScroll.value) {
              await nextTick()
              scrollToBottom()
            }
          
          }
        } catch (e) {
          console.error('解析JSON失败:', e)
        }
      }
    }
  } catch (error) {
    streamingText.value = '抱歉，发生了错误: ' + error.message
    messages.value[messages.value.length - 1].content = streamingText.value
  } finally {
    isStreaming.value = false
    //更新结果
    await window.dbAPI.invoke('session:addSession', {session_id,prompt,result:streamingText.value,time:Date.now()});
  }
}

// 滚动到底部
const scrollToBottom = () => {
  const chatBox = document.querySelector('.message')
  if (chatBox) {
    chatBox.scrollTop = chatBox.scrollHeight
  }
}


// 监听消息变化自动滚动
watch(messages, () => {
  if (autoScroll.value) {
    nextTick(() => {
      scrollToBottom()
    })
  }
}, { deep: true })

const handleClear = ()=>{
  messages.value = [{ role: 'assistant', content: '你好！我是AI助手，请问有什么可以帮你的？' }]
  session_id = crypto.randomUUID()
}



</script>

<style lang="scss" scoped>
.chat {
  display: flex;
  height: 97vh;
  margin: 10px auto;
  background-color: #fff;
  border-radius: 10px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  overflow: hidden;

  &-select{
    flex: 1;
    width: 100px;
    display: flex;
    flex-direction: column;
  }

  &-area {
    flex: 4;
    display: flex;
    flex-direction: column;
    max-width: 1200px;
  }

  &-content {
    display: flex;
    margin-bottom: 15px;
    max-width: 70%;
    flex-direction: inherit;
  }

  &-content-title {
    margin-top: 20px;
  }

  &-content-box {
    border-top-right-radius: 0;
  }

  &-his{
    height: 20px;
    overflow-x: hidden;
  }
  &-add-session-btn{
    //margin: 10px;
    margin: 0 auto;
  }
}








.message {
  flex: 1;
  padding: 20px;
  overflow-y: auto;
  background-color: #f9f9f9;
  display: flex;
  flex-direction: column;

  &-input {
    display: flex;
    padding: 15px;
    border-top: 1px solid #eee;
    align-items: center;
    background-color: #fff;
  }

  &-input-btn {
    margin-left: 20px;
    width: 55px;
    height: 55px;
    border-radius: 50%;
    background-color: #0084ff;
    color: white;
    border: none;
    margin-left: 10px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background-color 0.2s;
  }

  &-clear-btn {
    margin-right: 10px;
  }
}





/* Markdown 样式 */
 .markdown-content  :deep(pre) {
  background-color: #dde2e7;
  border-radius: 6px;
  padding: 16px;
  overflow: auto;
  margin: 8px 0;
}

.markdown-content  :deep(code) {
  font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
  background-color: rgba(27, 31, 35, 0.05);
  border-radius: 3px;
  padding: 0.2em 0.4em;
  font-size: 85%;
}

.markdown-content :deep(pre code) {
  background-color: transparent;
  padding: 0;
}

.markdown-content :deep(blockquote) {
  border-left: 4px solid #dfe2e5;
  color: #6a737d;
  padding: 0 1em;
  margin: 0 0 16px 0;
}

.markdown-content :deep(table) {
  border-collapse: collapse;
  margin: 16px 0;
  width: 100%;
}

.markdown-content :deep(table th),
.markdown-content :deep(table td) {
  padding: 6px 13px;
  border: 1px solid #dfe2e5;
}

.markdown-content :deep(table tr:nth-child(2n)) {
  background-color: #f6f8fa;
}
</style>